package com.lzq.shiro.controller;

import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.alibaba.fastjson.JSONObject;
import com.lzq.shiro.config.Constant;
import com.lzq.shiro.config.util.ShiroUtil;
import com.lzq.shiro.entity.ResponseEntity;
import com.lzq.shiro.entity.UserInfo;
import com.lzq.shiro.service.UserInfoService2;
import com.lzq.shiro.vo.RspUtil;

/**
 * Created by Administrator on 2017/12/11.
 */
@Controller
public class ShiroController {
	
	private Logger logger = Logger.getLogger(this.getClass());
	
	@Autowired
	private UserInfoService2 userInfoService2;
	
	@Autowired
	private RedisTemplate<Object , Object> redisTemplate;
	
	
	@GetMapping("/register")
	public String register() {
		return "register";
	}
	
	@GetMapping("/login")
	public String login() {
		return "login";
	}
	
	@GetMapping("/index")
	public String index() {
		return "index";
	}
	
	
	
	
	
	@PostMapping("/ajaxRegister")
	@ResponseBody
	public Map<String , Object> userRegister(@RequestBody UserInfo userInfo) {
		Map<String  , Object> result = new HashMap<String , Object>();
		try {
			// 首先判断用户的手机号码是否被注册了
			// 如果没有被注册，则进行用户注册操作
			result = userInfoService2.register(userInfo);  
			return result;
		} catch (Exception e) {
			e.printStackTrace();
			return RspUtil.rspErrMap(ResponseEntity.CORE_EXCP.getCode(), ResponseEntity.CORE_EXCP.getMessage());
		}
		
		
	}
	
	@GetMapping("/excpTest")
	@ResponseBody
	public Map<String , Object>  exceptionTest() {
		int a;
		try {
			a = 1/0;
		} catch (Exception e) {
			logger.error(e.getMessage() , e);
			return RspUtil.rspErrMap(ResponseEntity.CORE_EXCP.getCode(), ResponseEntity.CORE_EXCP.getMessage());
		}
		return RspUtil.rspMap(a);
	}
	

    /**
     * 登录方法
     * @param userInfo
     * @return
     */
    @RequestMapping(value = "/ajaxLogin", method = RequestMethod.POST)
    @ResponseBody
    public String ajaxLogin(UserInfo userInfo) {
        JSONObject jsonObject = new JSONObject();
        Subject subject = SecurityUtils.getSubject();
        boolean isAuthenticated = subject.isAuthenticated();
        if(isAuthenticated) {
        	logger.info("当前用户状态为已登陆");
        	jsonObject.put("token", subject.getSession().getId());
        	jsonObject.put("msg", "登录成功");
        	return jsonObject.toString();
        }
        UsernamePasswordToken token = new UsernamePasswordToken(userInfo.getUsername(), userInfo.getPassword());
        // 设置记住我
        if(!token.isRememberMe())
        	token.setRememberMe(true);
        try {
            subject.login(token);
            jsonObject.put("token", subject.getSession().getId());
            jsonObject.put("msg", "登录成功");
        } catch (IncorrectCredentialsException e) {
            jsonObject.put("msg", "密码错误");
        } catch (LockedAccountException e) {
            jsonObject.put("msg", "登录失败，该用户已被冻结");
        } catch (AuthenticationException e) {
            jsonObject.put("msg", "该用户不存在");
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return jsonObject.toString();
    }
    
    @GetMapping("/logout")
    public String logout() {
    	Subject subject = SecurityUtils.getSubject();
    	UserInfo userInfo = (UserInfo) subject.getPrincipal();
    	String mobile = null;
    	if(userInfo != null) {
    		mobile = userInfo.getMobile();
    	}
    	subject.logout();
    	logger.info(mobile + "退出登录成功");
    	return "redirect:/login";
    }
    
    
    @GetMapping("/findUserInfo")
    @ResponseBody
    public Map<String , Object> getUserInfoBySessionId(String sessionId , HttpServletRequest request , HttpServletResponse response){
    	
    	if(!ShiroUtil.isAuthenticated(sessionId, request, response)){
    		return RspUtil.rspErrMap(ResponseEntity.NOT_LOGIN.getCode(), ResponseEntity.NOT_LOGIN.getMessage());
    	}
    	UserInfo userInfo = ShiroUtil.getUserInfo(sessionId, request, response);
    	return RspUtil.rspMap(userInfo);
    }
    
    @GetMapping("/simplePrincipalColl")
    @ResponseBody
    public Object getSimplePrincipalCollectionFromRedis(String sessionId , HttpServletRequest request){
    	if(StringUtils.isBlank(sessionId)) {    		
    		Cookie[] cookies = request.getCookies();
    		if(cookies != null && cookies.length > 0) {
    			for(Cookie cookie : cookies) {
    				String cookieName = cookie.getName();
    				if(Constant.SHIRO_COOKIE_NAME.equals(cookieName)) {
    					sessionId = cookie.getValue();
    				}
    			}
    		}
    	}
    	Object result = redisTemplate.opsForValue().get(sessionId);
    	
    	return result;
    }
    
    

    /**
     * 未登录，shiro应重定向到登录界面，此处返回未登录状态信息由前端控制跳转页面
     * @return
     */
    @RequestMapping(value = "/unauth")
    @ResponseBody
    public Object unauth() {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("code", "1000000");
        map.put("msg", "未登录");
        return map;
    }
    
    
}
